package com.avalon.shop.service;

import com.avalon.core.exception.AvalonException;
import com.avalon.core.model.PageParam;
import com.avalon.core.model.RecordRow;
import com.avalon.core.util.JacksonUtil;
import com.avalon.core.util.RestTemplateUtils;
import com.avalon.core.util.StringUtils;
import com.avalon.shop.ShopContext;
import com.avalon.shop.config.ShopConfig;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public abstract class BaseService {
    protected final ShopConfig shopConfig;
    protected final ShopContext shopContext;

    protected abstract String getServiceName();

    public BaseService(ShopConfig shopConfig, ShopContext shopContext) {
        this.shopConfig = shopConfig;
        this.shopContext = shopContext;
    }

    public RecordRow addModel(Map<String, Object> value) {
        return addModel(getServiceName(), value);
    }

    public RecordRow addModel(String serviceName, Map<String, Object> value) {
        log.info("addModel 参数:" + value.toString());
        HashMap<String, Object> param = new HashMap<>();
        param.put("serviceName", serviceName);
        param.put("value", value);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("token", shopContext.getBackToken());
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/add",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            return JacksonUtil.convert2Map(responseEntity.getBody());
        } else {
            log.error("addModel 错误:" + responseEntity.getBody());
            throw new AvalonException(responseEntity.getBody());
        }
    }

    public void updateModel(Map<String, Object> value) {
        updateModel(getServiceName(), value);
    }

    public void updateModel(String serviceName, Map<String, Object> value) {
        log.info("updateModel 参数:" + value.toString());
        HashMap<String, Object> param = new HashMap<>();
        param.put("serviceName", serviceName);
        param.put("value", value);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("token", shopContext.getBackToken());
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/update",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {

        } else {
            log.error("updateModel 错误:" + responseEntity.getBody());
            throw new AvalonException(responseEntity.getBody());
        }
    }

    public void deleteModel(Integer id) {
        deleteModel(getServiceName(), id);
    }

    public void deleteModel(String serviceName, Integer id) {
        log.info("deleteModel 参数:" + id);
        HashMap<String, Object> param = new HashMap<>();
        param.put("serviceName", serviceName);
        param.put("id", id);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("token", shopContext.getBackToken());
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/delete",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {

        } else {
            log.error("deleteModel 错误:" + responseEntity.getBody());
            throw new AvalonException(responseEntity.getBody());
        }
    }

    public List<Map> getModelPage(String fields,
                                  Integer pageNum,
                                  Integer pageSize,
                                  String rpnCondition,
                                  String order) {
        return getModelPage(
                getServiceName(),
                fields,
                pageNum,
                pageSize,
                rpnCondition,
                order);
    }

    public List<Map> getModelPage(String serviceName,
                                  String fields,
                                  Integer pageNum,
                                  Integer pageSize,
                                  String rpnCondition,
                                  String order) {
        log.info("getModelPage 参数:serviceName={},fields={},pageNum={},pageSize={},rpnCondition={},order={}",
                serviceName, fields, pageNum, pageSize, rpnCondition, order);
        HashMap<String, Object> param = new HashMap<>();
        PageParam pageParam = new PageParam();
        pageParam.setPageNum(pageNum);
        pageParam.setPageSize(pageSize);
        param.put("page", pageParam);
        param.put("fields", fields);
        param.put("rpnCondition", rpnCondition);
        param.put("order", order);
        param.put("serviceName", serviceName);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("token", shopContext.getBackToken());
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/get/page",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            Map maps = JacksonUtil.convert2Object(responseEntity.getBody(),
                    new TypeReference<Map>() {
                    });
            return (List<Map>) maps.get("data");
        } else {
            log.error("getModelPage 错误:" + responseEntity.getBody());
            throw new AvalonException(responseEntity.getBody());
        }
    }

    public Map getModelDetail(String serviceName,
                              String fields,
                              String rpnCondition) {
        log.info("getModelDetail 参数:serviceName={},fields={},rpnCondition={}",
                serviceName, fields, rpnCondition);
        HashMap<String, Object> param = new HashMap<>();
        param.put("fields", fields);
        param.put("rpnCondition", rpnCondition);
        param.put("serviceName", serviceName);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("token", shopContext.getBackToken());
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/get/detail",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            if(StringUtils.isEmpty(responseEntity.getBody())) {
                return null;
            }
            return JacksonUtil.convert2Object(responseEntity.getBody(),
                    new TypeReference<Map>() {
                    });
        } else {
            log.error("getModelDetail 错误:" + responseEntity.getBody());
            throw new AvalonException(responseEntity.getBody());
        }
    }

    public Map getModelDetail(String serviceName,
                              String fields,
                              Integer id) {
        return getModelDetail(serviceName, fields, "(=,id," + id + ")");
    }

    public Map getModelDetail(String fields,
                              Integer id) {
        return getModelDetail(getServiceName(), fields, id);
    }


    public List<Map> getAllModel(String serviceName,
                                 String fields,
                                 String rpnCondition,
                                 String order) {
        log.info("getAllModel 参数:serviceName={},fields={},rpnCondition={}}",
                serviceName, fields, rpnCondition);
        HashMap<String, Object> param = new HashMap<>();
        param.put("fields", fields);
        param.put("rpnCondition", rpnCondition);
        param.put("order", order);
        param.put("serviceName", serviceName);
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("token", shopContext.getBackToken());
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(
                shopConfig.getServer() + "/model/get/all",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            return JacksonUtil.convert2Object(responseEntity.getBody(),
                    new TypeReference<List<Map>>() {
                    });
        } else {
            log.error("getAllModel 错误:" + responseEntity.getBody());
            throw new AvalonException(responseEntity.getBody());
        }
    }
}
